// -*-mode:c++; coding:utf-8-*-

#ifndef _XBASE_KV_SCANNER_HPP_
#define _XBASE_KV_SCANNER_HPP_

#include <boost/shared_ptr.hpp>

#include "sstable_block_cache_base.hpp"
#include "kv_scan_context.hpp"

namespace xbase {
	
	// interface
	class kv_scanner {
	public:
		typedef boost::shared_ptr<kv_scanner> pointer;

	public:
		kv_scanner (kv_scan_context::pointer p_context_ptr)
			: m_scan_context_ptr(p_context_ptr) {}

		virtual ~kv_scanner () {}

		//
		// 使用方式为：
		//
		// for(open_scanner(a); ! a.eos(); a.next())
		// {
		//     a.get();
		// }

		// 是否到达结束，只有该函数返回False，才可以调用get
		virtual bool eos() const = 0;

		// 将当前扫描器中的当前记录取出来，保证该调用的复杂度为1，并可重复调用
		virtual const block_entry &get() const = 0;

		// 取出下一条记录，并将当前扫描器中的当前记录换为下一条。
		// 如果到达结尾，则什么都不做。
		virtual void next() = 0;

		bool is_expired (uint32_t p_interval) const {
			return m_scan_context_ptr->is_expired(p_interval);
		}

		uint64_t id () const {
			return m_scan_context_ptr->id();
		}

		void update_timestamp () {
			return scan_context_ptr()->update_timestamp();
		}

		std::string tablet_name() const {
			return scan_context_ptr()->tablet_name();
		}

		const uint64_t &sequence_number() const {
			return m_sequence_number;
		}

	protected:
		kv_scan_context::pointer scan_context_ptr () const {
			return m_scan_context_ptr;
		}

		// 用来在比较当前Key相等的情况下，该值大的扫描器比较
		// 小，以保证Key相等的情况下，新的记录被先获取到。
		//
		// 主要用于标志sstable_scanner, memory_table_scanner，
		// 用在group_scanner中的比较函数中。其中，
		// memory_table_scanner要设置为最大的，因为它的数据是最
		// 新的。（可以取当前的日志序列号，可以保证是最大的）
		uint64_t m_sequence_number;
	private:
		kv_scan_context::pointer m_scan_context_ptr;
	};
} // namespace xbase


#endif	// _XBASE_KV_SCANNER_HPP_
